混和型變數是變數下的資料包含數字與類別型資料。例如一個張Titanic的船票的包廂(Cabin)號碼 -- A15。處理這種變數的方法之一,是將它拆成數字與類別變數兩個新的變數,然後再用我們之前討論的特徵工程方法,對這些新變數進行前置處理(preprocessing)。
混和型變數有兩種格式:
1.數字或非數字單獨出現在資料值內,就是一個變數下的資料可能是數字或字串,但兩者不會同時出現。例如一個變數包含 1-3, D, A 等數值。
以"mixed"變數為例,它下面的資料有數字與非數字兩種,但二者不會同時存在同一資料格內。
data = pd.read_csv('../input/Mixed_Variables.csv')
data.head()
/|id |mixed
------------- | -------------
0| 68407277| 1
1| 68355089| 1
2| 68341763| B
3| 66310712| 1
4| 68476807| A
檢視"mixed"變數。
data.mixed.unique()
array(['1', 'B', 'A', '0', '4', '3', '2', 'C', '6', '9'], dtype=object)
建立兩個新的變數,一個只包含數字,另一個只儲存文字(或字串)。
data['mixed_numerical'] = pd.to_numeric(data['mixed'], errors='coerce', downcast='integer')
data['mixed_categorical'] = np.where(data['mixed_num'].isnull(), data['mixed'], np.nan)
/|id| mixed |mixed_numerical| mixed_categorical
------------- | -------------
0 | 68407277| 1| 1.0| NaN
1| 68355089| 1| 1.0| NaN
2| 68341763| B| NaN| B
3| 66310712| 1| 1.0| NaN
4| 68476807| A| NaN |A
接下來,我們就可以用之前討論的方法,例如:我們可以用"Missing"來填補新類別欄位"mixed_categorical"的遺漏值。至於新數字欄位"mixed_numerical",可以用一個和新數字欄位內數值差距很大的數字來填補。
2.數字和非數字同時出現在資料值內,例如Titanic資料集下的"Cabin"變數有A15, A18, ...,"Ticket"變數下有A103349等資料。視情況而定,我們可以把它是視為是類別變數或將它拆成數字與類別變數兩個不同的變數。
以Kaggle的Titanic資料集中'Ticket'和'Cabin'兩個變數為例,將它們拆成數字與類別變數兩個不同的變數。
data = pd.read_csv('../input/titanic/train.csv', usecols=['Ticket', 'Cabin', 'Survived'])
data.head()
/|Survived| Ticket| Cabin
------------- | -------------
0| 0| A/5 21171| NaN
1| 1| PC 17599 |C85
2| 1 |STON/O2. 3101282| NaN
3| 1| 113803 |C123
4| 0| 373450 |NaN
對於"Cabin"變數,我們將第一個英文字元與其後數字分開,建立兩個新的變數,一個只包含數字,另一個只儲存文字(或字串)。
# 提取數字部分
data['Cabin_numerical'] = data.Cabin.str.extract('(\d+)')
# 提取第一個字元
data['Cabin_categorical'] = data['Cabin'].str[0]
data[['Cabin', 'Cabin_numerical', 'Cabin_categorical']].head()
/|Cabin| Cabin_numerical| Cabin_categorical
------------- | -------------
0| NaN| NaN| NaN
1 |C85| 85| C
2| NaN| NaN| NaN
3| C123| 123| C
4| NaN| NaN| NaN
檢視"Ticket"變數,可將第一部分視為類別變數,第二部分為數字。
data.Ticket.unique()
array(['A/5 21171', 'PC 17599', 'STON/O2. 3101282', '113803', '373450',
'330877', '17463', '349909', '347742', '237736', 'PP 9549',
'113783', 'A/5. 2151', '347082', '350406', '248706', '382652',
......
'349257', '7552', 'C.A./SOTON 34068', 'SOTON/OQ 392076', '211536',
'112053', '111369', '370376'], dtype=object)
data['Ticket_numerical'] = data.Ticket.apply(lambda s: s.split()[-1])
data['Ticket_numerical'] = np.where(data.Ticket_numerical.str.isdigit(), data.Ticket_numerical, np.nan)
data['Ticket_categorical'] = data.Ticket.apply(lambda s: s.split()[0])
data['Ticket_categorical'] = np.where(data.Ticket_categorical.str.isdigit(), np.nan, data.Ticket_categorical)
data[['Ticket', 'Ticket_categorical','Ticket_numerical']].head(10)
/|Ticket| Ticket_categorical| Ticket_numerical
------------- | -------------
0 |A/5 21171| A/5| 21171
1 |PC 17599| PC| 17599
2 |STON/O2. 3101282| STON/O2.| 3101282
3 |113803| NaN |113803
4| 373450| NaN |373450
...|...| ... |...
886 |211536| NaN| 211536
887| 112053| NaN| 112053
888 |W./C. 6607 |W./C. |6607
889 |111369 |NaN| 111369
890| 370376 |NaN| 370376
891 rows × 3 columns
比較轉換前後,類別總數差異。
print('Ticket 原本類別數: ', len(data.Ticket.unique()))
print('Cabin 原本類別數: ', len(data.Cabin.unique()))
print('新 Ticket類別欄位-- Ticket_categorical 類別數: ', len(data.Ticket_categorical.unique()))
print('新 Cabin類別欄位-- Cabin_categorical 類別數: ', len(data.Cabin_categorical.unique()))
Ticket 原本類別數: 681
Cabin 原本類別數: 148
新 Ticket類別欄位-- Ticket_categorical 類別數: 44
新 Cabin類別欄位-- Cabin_categorical 類別數: 9
新的類別變數的類別數目大量減少。